home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 August / CICA - The Ultimate Collection of Shareware for Windows (Disc 2) (August 1995).iso / disc2 / nt / source.exe / POSIX / ELVIS / REGSUB.C < prev    next >
C/C++ Source or Header  |  1992-09-26  |  4KB  |  204 lines

  1. /* regsub.c */
  2.  
  3. /* This file contains the regsub() function, which performs substitutions
  4.  * after a regexp match has been found.
  5.  */
  6.  
  7. #include <ctype.h>
  8. #include "config.h"
  9. #include "vi.h"
  10. #include "regexp.h"
  11.  
  12. static char *previous;    /* a copy of the text from the previous substitution */
  13.  
  14. /* perform substitutions after a regexp match */
  15. void regsub(re, src, dst)
  16.     regexp        *re;
  17.     REG char    *src;
  18.     REG char    *dst;
  19. {
  20.     REG char    *cpy;
  21.     REG char    *end;
  22.     REG char    c;
  23.     char        *start;
  24. #ifndef CRUNCH
  25.     int        mod;
  26.  
  27.     mod = 0;
  28. #endif
  29.  
  30.     start = src;
  31.     while ((c = *src++) != '\0')
  32.     {
  33. #ifndef NO_MAGIC
  34.         /* recognize any meta characters */
  35.         if (c == '&' && *o_magic)
  36.         {
  37.             cpy = re->startp[0];
  38.             end = re->endp[0];
  39.         }
  40.         else if (c == '~' && *o_magic)
  41.         {
  42.             cpy = previous;
  43.             if (cpy)
  44.                 end = cpy + strlen(cpy);
  45.         }
  46.         else
  47. #endif /* not NO_MAGIC */
  48.         if (c == '\\')
  49.         {
  50.             c = *src++;
  51.             switch (c)
  52.             {
  53. #ifndef NO_MAGIC
  54.               case '0':
  55.               case '1':
  56.               case '2':
  57.               case '3':
  58.               case '4':
  59.               case '5':
  60.               case '6':
  61.               case '7':
  62.               case '8':
  63.               case '9':
  64.                 /* \0 thru \9 mean "copy subexpression" */
  65.                 c -= '0';
  66.                 cpy = re->startp[c];
  67.                 end = re->endp[c];
  68.                 break;
  69. # ifndef CRUNCH
  70.               case 'U':
  71.               case 'u':
  72.               case 'L':
  73.               case 'l':
  74.                 /* \U and \L mean "convert to upper/lowercase" */
  75.                 mod = c;
  76.                 continue;
  77.  
  78.               case 'E':
  79.               case 'e':
  80.                 /* \E ends the \U or \L */
  81.                 mod = 0;
  82.                 continue;
  83. # endif /* not CRUNCH */
  84.               case '&':
  85.                 /* "\&" means "original text" */
  86.                 if (*o_magic)
  87.                 {
  88.                     *dst++ = c;
  89.                     continue;
  90.                 }
  91.                 cpy = re->startp[0];
  92.                 end = re->endp[0];
  93.                 break;
  94.  
  95.               case '~':
  96.                 /* "\~" means "previous text, if any" */
  97.                 if (*o_magic)
  98.                 {
  99.                     *dst++ = c;
  100.                     continue;
  101.                 }
  102.                 cpy = previous;
  103.                 if (cpy)
  104.                     end = cpy + strlen(cpy);
  105.                 break;
  106. #else /* NO_MAGIC */
  107.               case '&':
  108.                 /* "\&" means "original text" */
  109.                 cpy = re->startp[0];
  110.                 end = re->endp[0];
  111.                 break;
  112.  
  113.               case '~':
  114.                 /* "\~" means "previous text, if any" */
  115.                 cpy = previous;
  116.                 if (cpy)
  117.                     end = cpy + strlen(cpy);
  118.                 break;
  119. #endif /* NO_MAGIC */
  120.               default:
  121.                 /* ordinary char preceded by backslash */
  122.                 *dst++ = c;
  123.                 continue;
  124.             }
  125.         }
  126.         else
  127.         {
  128.             /* ordinary character, so just copy it */
  129.             *dst++ = c;
  130.             continue;
  131.         }
  132.  
  133.         /* Note: to reach this point in the code, we must have evaded
  134.          * all "continue" statements.  To do that, we must have hit
  135.          * a metacharacter that involves copying.
  136.          */
  137.  
  138.         /* if there is nothing to copy, loop */
  139.         if (!cpy)
  140.             continue;
  141.  
  142.         /* copy over a portion of the original */
  143.         while (cpy < end)
  144.         {
  145. #ifndef NO_MAGIC
  146. # ifndef CRUNCH
  147.             switch (mod)
  148.             {
  149.               case 'U':
  150.               case 'u':
  151.                 /* convert to uppercase */
  152.                 if (isascii(*cpy) && islower(*cpy))
  153.                 {
  154.                     *dst++ = toupper(*cpy);
  155.                     cpy++;
  156.                 }
  157.                 else
  158.                 {
  159.                     *dst++ = *cpy++;
  160.                 }
  161.                 break;
  162.  
  163.               case 'L':
  164.               case 'l':
  165.                 /* convert to lowercase */
  166.                 if (isascii(*cpy) && isupper(*cpy))
  167.                 {
  168.                     *dst++ = tolower(*cpy);
  169.                     cpy++;
  170.                 }
  171.                 else
  172.                 {
  173.                     *dst++ = *cpy++;
  174.                 }
  175.                 break;
  176.  
  177.               default:
  178.                 /* copy without any conversion */
  179.                 *dst++ = *cpy++;
  180.             }
  181.  
  182.             /* \u and \l end automatically after the first char */
  183.             if (mod && (mod == 'u' || mod == 'l'))
  184.             {
  185.                 mod = 0;
  186.             }
  187. # else /* CRUNCH */
  188.             *dst++ = *cpy++;
  189. # endif /* CRUNCH */
  190. #else /* NO_MAGIC */
  191.             *dst++ = *cpy++;
  192. #endif /* NO_MAGIC */
  193.         }
  194.     }
  195.     *dst = '\0';
  196.  
  197.     /* remember what text we inserted this time */
  198.     if (previous)
  199.         free(previous);
  200.     previous = (char *)malloc((unsigned)(strlen(start) + 1));
  201.     if (previous)
  202.         strcpy(previous, start);
  203. }
  204.